/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufsc.aps.convocados;

import br.ufsc.inf.leobr.cliente.Jogada;
import javax.swing.JOptionPane;

/**
 *
 * @author gustavo.ramos
 */
public class Tabuleiro {

    private Tecnico t1;
    private Tecnico t2;
    private Baralho deck = new Baralho();
    private int controleTrocaEsquema = 0;

    public Baralho getBaralho() {
        return deck;
    }

    public void executarSubstituicao() {
    }

    /**
     * @return the t1
     */
    public Tecnico getT1() {
        return t1;
    }

    /**
     * @param t1 the t1 to set
     */
    public void setT1(Tecnico t1) {
        this.t1 = t1;
    }

    private boolean defesaContem(Jogador substituido) {
        return this.getT1().getDefesa().getJogadores().contains(substituido);
    }

    private void definirPosicoes(Posicao posicaoDefesa, Posicao posicaoMeio, Posicao posicaoAtaque) {
        this.getT2().setDefesa(posicaoDefesa);
        this.getT2().setMeio(posicaoMeio);
        this.getT2().setAtaque(posicaoAtaque);
    }

    private void incrementaControleEsquema() {
        setControleTrocaEsquema(getControleTrocaEsquema() + 1);
    }

    private void initCoisas() {
    }

    /**
     * Creates new form Tabuleiro
     */
    public Tabuleiro() {
        initCoisas();
    }

    /**
     * @return the t2
     */
    protected Tecnico getT2() {
        return t2;
    }

    /**
     * @param t2 the t2 to set
     */
    protected void setT2(Tecnico t2) {
        this.t2 = t2;
    }

    /**
     * @param bar the baralho to set
     */
    public void setBaralho(Baralho bar) {
        this.deck = bar;
    }

    public void resetAndOrder(Integer ordem) {
        deck = new Baralho();
        if (ordem == 1) {
            t1.setDaVez(true);
            t2.setDaVez(false);
        } else {
            t2.setDaVez(true);
            t1.setDaVez(false);
        }
    }

    public void criarTecnicos(String nome, String nomeOponente) {
        t1 = new Tecnico();
        t1.setNome(nome);
        t2 = new Tecnico();
        t2.setNome(nomeOponente);
    }

//    public void receberJogada(Jogada jogada) {
//        Lance l = (Lance) jogada;
//        this.tratarLance(l);
//            
//    }
    public TipoLance receberJogada(Jogada jogada) {
        Lance l = (Lance) jogada;
        this.tratarLance(l);
        return l.getTipoLance();
    }

    private boolean meioContem(Jogador substituido) {
        return this.getT1().getMeio().getJogadores().contains(substituido);
    }

    private void tratarLance(Lance l) {
        setBaralho(l.getBaralho());
        t1.setDaVez(true);
        t2.setDaVez(false);
        if (l.getTipoLance() == TipoLance.FIM_DO_INICIO_DE_JOGO || l.getTipoLance() == TipoLance.INICIO_JOGO) {
            //montar posicao oponente            
            t2.setDefesa(l.getPosicaoDefesa());
            t2.setMeio(l.getPosicaoMeio());
            t2.setAtaque(l.getPosicaoAtaque());
            t2.setEsquemaAtual(new EsquemaTatico(l.getPosicaoDefesa().getLimiteMaximoPosicao(), l.getPosicaoMeio().getLimiteMaximoPosicao(), l.getPosicaoAtaque().getLimiteMaximoPosicao()));
            //--
        } else if (l.getTipoLance() == TipoLance.ADICIONAR_JOGADOR || l.getTipoLance() == TipoLance.COMPLETAR_JOGO) {
            this.adicionarJogadorOponenente(l.getJogadorAdicionado(), l.getTipoPosicaoEmQueJogadorFoiAdicionado());
            zerarControleEsquema();
        } else if (l.getTipoLance() == TipoLance.SUBSTITUIR_JOGADOR) {
            this.substituirJogadorOponente(l.getJogadorAdicionado(), l.getJogadorSubstituido(), l.getTipoPosicaoEmQueJogadorFoiAdicionado());
            zerarControleEsquema();
        } else if (l.getTipoLance() == TipoLance.TROCAR_ESQUEMA) {
            this.trocarEsquemaOponente(l.getPosicaoDefesa(), l.getPosicaoMeio(), l.getPosicaoAtaque());
            incrementaControleEsquema();
        } else if (l.getTipoLance() == TipoLance.FIM_DE_JOGO) {
            definirPosicoes(l.getPosicaoDefesa(), l.getPosicaoMeio(), l.getPosicaoAtaque());
        }
    }

    private void zerarControleEsquema() {
        setControleTrocaEsquema(0);
    }

    public void distribuirValoresIniciais() {
        t1.setJogadores(deck.sortearJogadoresInicio());
        t1.setEsquemas(deck.sortearEsquemasInicio());
    }

    public void montarEsquema(EsquemaTatico esq) {
        t1.setEsquemaAtual(esq);
        t1.setEsquemaReserva(t1.getEsquemas().get(0));
        t1.setDefesa(new Posicao(TipoPosicao.DEFESA, esq.getDefesa()));
        t1.setMeio(new Posicao(TipoPosicao.MEIO, esq.getMeio()));
        t1.setAtaque(new Posicao(TipoPosicao.ATAQUE, esq.getAtaque()));
        //------
    }

    public String trocarEsquema() {
        if (getT1().isDaVez()) {
            if (getControleTrocaEsquema() < 2) {
                this.incrementaControleEsquema();
                this.getT1().trocarEsquemaTatico();
                return null;
            } else {
                return "Não é permitida 3 trocas de Esquema Tático consecutivas";
            }

        } else {
            return "Não é minha vez.";
        }
    }

    public TipoPosicao subsituirJogadores(Jogador jogadorNovo, Jogador substituido) {
        zerarControleEsquema();
        TipoPosicao tp;
        if (defesaContem(substituido)) {
            this.getT1().getDefesa().substituirJogador(jogadorNovo, substituido);
            tp = TipoPosicao.DEFESA;

        } else if (meioContem(substituido)) {
            this.getT1().getMeio().substituirJogador(jogadorNovo, substituido);
            tp = TipoPosicao.MEIO;

        } else {
            this.getT1().getAtaque().substituirJogador(jogadorNovo, substituido);
            tp = TipoPosicao.ATAQUE;

        }
        this.getT1().getJogadores().remove(jogadorNovo);
        this.getT1().getJogadores().add(this.getBaralho().comprarJogador());
        this.getT1().setQuantidadeSubstituicao(this.getT1().getQuantidadeSubstituicao() + 1);

        return tp;
    }

    public void adicionarJogadorOponenente(Jogador jogador, TipoPosicao tp) {
        if (tp.equals(TipoPosicao.DEFESA)) {
            getT2().getDefesa().adicionarJogador(jogador);
        } else if (tp.equals(TipoPosicao.MEIO)) {
            getT2().getMeio().adicionarJogador(jogador);
        } else {
            getT2().getAtaque().adicionarJogador(jogador);
        }
    }

    public String adicionarJogador(Jogador jogador, TipoPosicao tp, boolean isTrocaEsquema) {
        if (getT1().isDaVez()) {
            int i = getT1().getJogadores().indexOf(jogador);

            if (tp.equals(TipoPosicao.DEFESA)) {
                if (getT1().getDefesa().getNumeroJogadores() < getT1().getDefesa().getLimiteMaximoPosicao()) {
                    getT1().getDefesa().adicionarJogador(isTrocaEsquema ? jogador : getT1().getJogadores().remove(i));
                } else {
                    return "Limite de Jogadores excedido na defesa!";
                }
            } else if (tp.equals(TipoPosicao.MEIO)) {
                if (getT1().getMeio().getNumeroJogadores() < getT1().getMeio().getLimiteMaximoPosicao()) {
                    getT1().getMeio().adicionarJogador(isTrocaEsquema ? jogador : getT1().getJogadores().remove(i));
                } else {
                    return "Limite de Jogadores excedido no meio campo!";
                }

            } else {
                if (getT1().getAtaque().getNumeroJogadores() < getT1().getAtaque().getLimiteMaximoPosicao()) {
                    getT1().getAtaque().adicionarJogador(isTrocaEsquema ? jogador : getT1().getJogadores().remove(i));
                } else {
                    return "Limite de Jogadores excedido no ataque!";
                }
            }
            //TO DO
            //se oponene tiver 10 cartas na mesa, não se deve adicionar outra carta na mão
            if (!isTrocaEsquema) {
                zerarControleEsquema();
                getT1().addJogador(getBaralho().comprarJogador());
            }
        } else {
            return "Não é minha vez!";
        }
        return null;
    }

    private void substituirJogadorOponente(Jogador jogadorAdicionado, Jogador jogadorSubstituido, TipoPosicao tipoPosicaoEmQueJogadorFoiAdicionado) {
        if (tipoPosicaoEmQueJogadorFoiAdicionado.equals(TipoPosicao.DEFESA)) {
            getT2().getDefesa().substituirJogador(jogadorAdicionado, jogadorSubstituido);
        } else if (tipoPosicaoEmQueJogadorFoiAdicionado.equals(TipoPosicao.MEIO)) {
            getT2().getMeio().substituirJogador(jogadorAdicionado, jogadorSubstituido);
        } else {
            getT2().getAtaque().substituirJogador(jogadorAdicionado, jogadorSubstituido);
        }
    }

    private void trocarEsquemaOponente(Posicao posicaoDefesa, Posicao posicaoMeio, Posicao posicaoAtaque) {
        this.definirPosicoes(posicaoDefesa, posicaoMeio, posicaoAtaque);
        getT2().setEsquemaAtual(new EsquemaTatico(posicaoDefesa.getLimiteMaximoPosicao(), posicaoMeio.getLimiteMaximoPosicao(), posicaoAtaque.getLimiteMaximoPosicao()));
    }

    public boolean tratarFimDeJogo() {
        boolean empate = verificarEmpate();
        if (empate) {
            return verificarPontuacaoTotalGeral();
        } else {
            return verificarPontuacaoGeralPorPosicao();
        }
    }

    private boolean verificarPontuacaoGeralPorPosicao() {
        int defesaT1 = getT1().getDefesa().getTotalPontuacao();
        int meioT1 = getT1().getMeio().getTotalPontuacao();
        int ataqueT1 = getT1().getAtaque().getTotalPontuacao();
        int defesaT2 = getT2().getDefesa().getTotalPontuacao();
        int meioT2 = getT2().getMeio().getTotalPontuacao();
        int ataqueT2 = getT2().getAtaque().getTotalPontuacao();
        int soma = 0;
        if (defesaT1 > ataqueT2) {
            soma++;
        }
        if (meioT1 > meioT2) {
            soma++;
        }
        if (ataqueT1 > defesaT2) {
            soma++;
        }
        return soma >= 2;
    }

    private boolean verificarPontuacaoTotalGeral() {
        int pontosT1 = getT1().getDefesa().getTotalPontuacao() + getT1().getMeio().getTotalPontuacao() + getT1().getAtaque().getTotalPontuacao();
        int pontosT2 = getT2().getDefesa().getTotalPontuacao() + getT2().getMeio().getTotalPontuacao() + getT2().getAtaque().getTotalPontuacao();
        return pontosT1 > pontosT2;
    }

    private boolean verificarEmpate() {
        if (getT1().getDefesa().getTotalPontuacao().equals(getT2().getAtaque().getTotalPontuacao())
                || getT1().getMeio().getTotalPontuacao().equals(getT2().getMeio().getTotalPontuacao())
                || getT1().getAtaque().getTotalPontuacao().equals(getT2().getDefesa().getTotalPontuacao())) {
            return true;
        } else {
            return false;
        }
    }

    void reset() {
        t1 = null;
        t2 = null;
    }

    public int verificarSePodeSubstituir() {
        if (!this.getT1().isDaVez()) {
            return 1;
        } else if (this.getT1().getQuantidadeSubstituicao() >= 3) {
            return 2;
        } else {
            return 0;
        }
    }

    /**
     * @return the controleTrocaEsquema
     */
    public int getControleTrocaEsquema() {
        return controleTrocaEsquema;
    }

    /**
     * @param controleTrocaEsquema the controleTrocaEsquema to set
     */
    public void setControleTrocaEsquema(int controleTrocaEsquema) {
        this.controleTrocaEsquema = controleTrocaEsquema;
    }
}
